package com.gitee.wsl.mathematics.vector.ext


import com.gitee.wsl.mathematics.base.Mapping2
import com.gitee.wsl.mathematics.base.Mapping3
import com.gitee.wsl.mathematics.base.Mapping4
import com.gitee.wsl.mathematics.base.NumberMapping
import com.gitee.wsl.mathematics.base.NumberMapping2
import com.gitee.wsl.mathematics.vector.vec2.Vector2
import com.gitee.wsl.mathematics.vector.vec3.Vector3
import com.gitee.wsl.mathematics.vector.vec4.Vector4


/** Call [map] on [Vec2.x] and [Vec2.y] components and then call [reduce] accepting results of the mappings. */
inline fun <A:Number,T, R> Vector2<A,*>.mapReduce(map: NumberMapping<A,T>, reduce: Mapping2<T, R>) = reduce(map(x), map(y))

/** Call [map] on [Vec3.x], [Vec3.y], and [Vec3.z] components and then call [reduce] accepting results of the
 * mappings. */
inline fun <A:Number,T, R> Vector3<A, *>.mapReduce(map: NumberMapping<A,T>, reduce: Mapping3<T, R>) =
    reduce(map(x), map(y), map(z))

/** Call [map] on [Vec4.x], [Vec4.y], [Vec4.z], and [Vec4.w] components and then call [reduce] accepting results of
 * the mappings. */
inline fun <A:Number,T, R> Vector4<A, *>.mapReduce(map: NumberMapping<A,T>, reduce: Mapping4<T, R>) =
    reduce(map(x), map(y), map(z), map(w))

/** Call [map] on pairs ([Vec2.x], [b].x) and ([Vec2.y], [b].y) and then call [reduce] accepting results of the
 * mappings. */
inline fun <A:Number,T, R> Vector2<A,*>.mapReduce(b: Vector2<A,*>, map: NumberMapping2<A, T> , reduce: Mapping2<T, R>) =
    reduce(map(x, b.x), map(y, b.y))

/** Call [map] on pairs ([Vec3.x], [b].x), ([Vec3.y], [b].y), and ([Vec3.z], [b].z) and then call [reduce] accepting
 * results of the mappings. */
inline fun <A:Number,T, R> Vector3<A,*>.mapReduce(b: Vector3<A,*>, map: NumberMapping2<A, T> , reduce: Mapping3<T, R>) =
    reduce(map(x, b.x), map(y, b.y), map(z, b.z))

/** Call [map] on pairs ([Vec4.x], [b].x), ([Vec4.y], [b].y), ([Vec4.z], [b].z), and ([Vec4.w], [b].w) and then call
 * [reduce] accepting results of the mappings. */
inline fun <A:Number,T, R> Vector4<A,*>.mapReduce(b: Vector4<A,*>, map: NumberMapping2<A, T> , reduce: Mapping4<T, R>) =
    reduce(map(x, b.x), map(y, b.y), map(z, b.z), map(w, b.w))
